﻿using System;
using System.Diagnostics;
using System.Security.Cryptography;
using System.Text;
using System.Windows.Forms;
using LinqToTwitter;

namespace SocialMediaIntegrationPack
{
    public static class Authentication
    {
        #region Delegates

        public delegate string GetPinCode(Form dialogueForm);

        #endregion

        #region Result enum

        public enum Result
        {
            Successful,
            Unauthorized,
            UserCancelled,
            DestinationUnreachable
        } ;

        #endregion

        //Encrypted if USE_HASHING is set to true
        private const string CONSUMER_KEY = "Put ur API Key here";
        private const string CONSUMER_SECRET = "Put ur API Secret here";

        private const string KEY = "put ur DES key here is use encrypting";
        private const bool USE_HASHING = false;

        private static string ConsumerKey
        {
            get { return Decrypt(CONSUMER_KEY); }
        }

        private static string ConsumerSecret
        {
            get { return Decrypt(CONSUMER_SECRET); }
        }

        public static ITwitterAuthorizer AuthenticateViaPin(GetPinCode getPinCode, Form dialogueForm)
        {
            PinAuthorizer pinAuthorizer = PinAuthorizeGetsAccessToken(CONSUMER_KEY, CONSUMER_SECRET, getPinCode,
                                                                      dialogueForm);
            return pinAuthorizer != null ? (!pinAuthorizer.IsAuthorized ? null : pinAuthorizer) : pinAuthorizer;
        }

        public static ITwitterAuthorizer Authenticate(string accessToken, string accessTokenSecret)
        {
            var auth = new SingleUserAuthorizer
                           {
                               Credentials = new InMemoryCredentials
                                                 {
                                                     ConsumerKey = ConsumerKey,
                                                     ConsumerSecret = ConsumerSecret,
                                                     OAuthToken = Decrypt(accessToken),
                                                     AccessToken = Decrypt(accessTokenSecret)
                                                 }
                           };
            return auth;
        }

        public static PinAuthorizer PinAuthorizeGetsAccessToken(string consumerKey, string consumerSecret,
                                                                GetPinCode getPinCode, Form dialogueForm)
        {
            try
            {
                // Configure the OAuth object
                var auth = new PinAuthorizer
                               {
                                   Credentials = new InMemoryCredentials
                                                     {
                                                         ConsumerKey = Decrypt(consumerKey),
                                                         ConsumerSecret = Decrypt(consumerSecret)
                                                     },
                                   UseCompression = true,
                                   GoToTwitterAuthorization = pageLink => Process.Start(pageLink),
                                   GetPin = () => getPinCode(dialogueForm)
                               };

                // Start the authorization process (launches Twitter authorization page).
                auth.Authorize();
                return auth;
            }
            catch (Exception)
            {
                return null;
            }
        }


        public static string Encrypt(string toEncrypt)
        {
            if (!USE_HASHING)
                return toEncrypt;
            var toEncryptArray = Encoding.UTF8.GetBytes(toEncrypt);

            var hashmd5 = new MD5CryptoServiceProvider();
            var keyArray = hashmd5.ComputeHash(Encoding.UTF8.GetBytes(KEY));

            hashmd5.Clear();

            var tdes = new TripleDESCryptoServiceProvider
                           {
                               Key = keyArray,
                               Mode = CipherMode.ECB,
                               Padding = PaddingMode.PKCS7
                           };

            var cTransform = tdes.CreateEncryptor();
            var resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
            tdes.Clear();
            return Convert.ToBase64String(resultArray, 0, resultArray.Length);
        }

        public static string Decrypt(string cipherString)
        {
            if (!USE_HASHING)
                return cipherString;
            var toEncryptArray = Convert.FromBase64String(cipherString);

            var hashmd5 = new MD5CryptoServiceProvider();
            var keyArray = hashmd5.ComputeHash(Encoding.UTF8.GetBytes(KEY));

            hashmd5.Clear();

            var tdes = new TripleDESCryptoServiceProvider
                           {
                               Key = keyArray,
                               Mode = CipherMode.ECB,
                               Padding = PaddingMode.PKCS7
                           };

            var cTransform = tdes.CreateDecryptor();
            var resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
            tdes.Clear();
            return Encoding.UTF8.GetString(resultArray);
        }
    }

    public class InternetConnectionException : Exception
    {
        // empty
    }
}